#include <Fonts.h>
#include <Menus.h>
#include <Events.h>
#include <Dialogs.h>
#include <SANE.h>
#include <Packages.h>


#define	DIALOGID		512
#define	INTEGERITEM		3
#define	FIXEDITEM		4
#define	FLOATITEM		5

Resume() {
	ExitToShell();
}
	

pascal Boolean FilterNonNumeric(dialog, event, itemHit)
		DialogPeek	dialog;
		EventRecord	*event;
		short		*itemHit;
{
	auto	Boolean	filtered;
	auto	char	chr;
	auto	short	type;	
	auto	long	ticks;
	auto	Handle	itemHdle;
	auto	Rect	rect;
	
	filtered = false;
	if (keyDown == event->what || autoKey == event->what) {
		chr = event->message & charCodeMask;
		if (' ' > chr) { 
			if ('\n' == chr || '\03' == chr) {
				/*
				** process return and enter key presses
				*/
				GetDItem((DialogPtr)dialog, ok, &type, &itemHdle, &rect);
				HiliteControl((ControlHandle)itemHdle, 1);
				Delay(15, &ticks);
				HiliteControl((ControlHandle) itemHdle, 0);
				filtered = true;
				*itemHit = ok;
		
			} else if ('\t' != chr && '\b' != chr) {
				filtered = true;
			} 
		} else {
			/*
			** filter out the inappropriate key presses
			*/
			switch(dialog->editField + 1) {
			case INTEGERITEM :
				if ((chr < '0' || '9' < chr)
				&& chr != '+' && chr != '-') {
					filtered = true;
					*itemHit = INTEGERITEM;
				}
				break;
			case FIXEDITEM :
				if ((chr < '0' || '9' < chr)
				&& chr != '.' && chr != '+' && chr != '-') {
					filtered = true;
					*itemHit = FIXEDITEM;
				}
				break;
			case FLOATITEM :
				if ((chr < '0' || '9' < chr) 
				&& chr != 'e' && chr != 'E'
				&& chr != '.' && chr != '+' && chr != '-') {
					filtered = true;
					*itemHit = FLOATITEM;
				}
				break;
			}
		}
	}
	return filtered;
}

main () {

	auto	DialogPtr	dialog;
	auto	Handle		itemHandle;
	auto	short		itemHit;
	auto	short		itemType;
	auto	Rect		rect;
	
	auto	decform		decForm;
	auto	char		string[255];
	auto	short		index;
	auto	decimal		dec;
	auto	short		validInput;
	
	auto	long		k;
	auto	double		x, y;
	
	/*
	** initialize the macintosh
	*/
	InitGraf((Ptr) &qd.thePort);
	InitFonts();
	InitWindows();
	InitMenus();
	TEInit();
	InitDialogs((ResumeProcPtr) Resume);
	InitCursor();
	
	/*
	** create the dialog window and initialize the edit fields
	*/
	dialog = GetNewDialog(DIALOGID, 0L, (WindowPtr) -1L);
	SetPort(dialog);
	GetDItem(dialog, ok, &itemType, &itemHandle, &rect);
	PenSize(3, 3);
	InsetRect(&rect, -4, -4);
	FrameRoundRect(&rect, 16, 16);
	PenSize(1, 1);
	
	/*
	** the first field is an integer
	*/
	k = 123;
	NumToString(k, string);
	GetDItem(dialog, INTEGERITEM, &itemType, &itemHandle, &rect);
	SetIText(itemHandle, string);
	
	/*
	** the second field is a fixed point number
	*/
	x = 123.456;
	decForm.style = FIXEDDECIMAL;
	decForm.digits = 2;
	num2dec(&decForm, x, &dec);
	decForm.style = FIXEDDECIMAL;
	decForm.digits = 6;
	dec2str(&decForm, &dec, string);
	c2pstr(string);
	GetDItem(dialog, FIXEDITEM, &itemType, &itemHandle, &rect);
	SetIText(itemHandle, string);
	
	/*
	** the third field is a floating point number
	*/
	y = 0.123456;
	decForm.style = FLOATDECIMAL;
	decForm.digits = 4;
	num2dec(&decForm, y, &dec);
	decForm.style = FLOATDECIMAL;
	decForm.digits = 6;
	dec2str(&decForm, &dec, string);	
	c2pstr(string);
	GetDItem(dialog, FLOATITEM, &itemType, &itemHandle, &rect);
	SetIText(itemHandle, string);
	
	/*
	** process user actions until they get it correct or cancel
	*/
	validInput = false;
	do {
		ModalDialog(FilterNonNumeric, &itemHit);
		switch (itemHit) {
		case ok :
		
			/*
			** check the validity of the text in the integer field
			*/
			GetDItem(dialog, INTEGERITEM, &itemType, &itemHandle, &rect);
			GetIText(itemHandle, string);
			p2cstr(string);
			index = 0;
			str2dec(string, &index, &dec, &validInput);
			c2pstr(string);
			if (!validInput) {
				SysBeep(1);
				SelIText(dialog, INTEGERITEM, index, 32767);
				break;
			} else {
				StringToNum(string, &k);
			}
			
			/*
			** check the validity of the text in the fixed point field
			*/
			GetDItem(dialog, FIXEDITEM, &itemType, &itemHandle, &rect);
			GetIText(itemHandle, string);
			p2cstr(string);
			index = 0;
			str2dec(string, &index, &dec, &validInput);
			if (!validInput) {
				SysBeep(1);
				SelIText(dialog, FIXEDITEM, index, 32767);
				break;
			} else {
				x = dec2num(&dec);
			}
			
			/*
			** check the validity of the text in the floating point field
			*/
			GetDItem(dialog, FLOATITEM, &itemType, &itemHandle, &rect);
			GetIText(itemHandle, string);
			p2cstr(string);
			index = 0;
			str2dec(string, &index, &dec, &validInput);
			if (!validInput) {
				SysBeep(1);
				SelIText(dialog, FLOATITEM, index, 32767);
				break;
			} else {
				y = dec2num(&dec);
			}
			
			break;
			
		case cancel :
			break;
		}
	} while (!validInput && cancel != itemHit);
	
	DisposDialog(dialog);
	
	/*
	** you would probably do something with the numbers at this point
	*/
	ExitToShell();
	
}
